package cn.edu.nju.ws.sview.views;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;

import cn.edu.nju.ws.sview.cache.GroupCache;
import cn.edu.nju.ws.sview.cache.GroupNameIDCache;
import cn.edu.nju.ws.sview.cache.UserNameIDCache;
import cn.edu.nju.ws.sview.database.DBConnectionFactory;

/**
 * 编辑组对象
 * @author Saisai Gong
 *
 */
public class Group {
	private String name;
	private String admin;
	
	/**
	 * construct function
	 * @param name. group name
	 * @param admin. admin name
	 * @return
	 */
	public Group(String name,String admin){
		if(admin==null)
			throw new IllegalArgumentException("Admin can not be null");
		this.name = name;
		this.admin = admin;
	}
	
	/**
	 * add member of the group in the database
	 * @param groupID
	 */
	public static void addMember(int groupID,ArrayList<String> users){
		Connection conn = DBConnectionFactory.getConnection();
		try {
			PreparedStatement pstmt = conn.prepareStatement("insert ignore into group_member(gid,uid,time) values(?,?,?)");
			pstmt.setInt(1, groupID);
			for(String user:users){
				try {
					int uid = UserNameIDCache.getInstance().getUserID(user);
					pstmt.setInt(2, uid);
					pstmt.setTimestamp(3, new java.sql.Timestamp(new Date().getTime())) ;
					pstmt.executeUpdate();
					GroupCache.getInstance().updateGroupIDs(uid);
				} catch (Throwable e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			pstmt.close();
			conn.close();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static int getGroupIdByName(String groupName) {
		int id = -1;
		if(groupName==null)
			return id;
		try {
			int mid =  GroupNameIDCache.getInstance().getGroupID(groupName) ;
			if(mid>0)
				id = mid;
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return id;
	}
	
	public static String getGroupNameById(int groupID){
		String name = null;
	     try {
			name = GroupNameIDCache.getInstance().getName(groupID) ;
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return name;
	}
	
	/**
	 * get the admin of the group
	 * @param groupID
	 */
	public  static String getAdmin(int groupID){
        String result = null;
		try {
			Connection conn = DBConnectionFactory.getConnection();
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(String.format(
					"select admin_id from edit_group where id=%d",groupID));
			while(rs.next()){
				int admin_id = rs.getInt("admin_id") ;
				try {
					result = UserNameIDCache.getInstance().getName(admin_id) ;
				} catch (Throwable e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			rs.close();
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * get the group members
	 * @param groupID
	 * @return
	 */
	public static ArrayList<String> getMembers(int groupID){
		ArrayList<String> result = new ArrayList<String>();
		try {
			Connection conn = DBConnectionFactory.getConnection();
			Statement stmt = conn.createStatement();
			ResultSet rs = stmt.executeQuery(String.format(
					"select uid from group_member where gid=%d",groupID));
			while(rs.next()){
				int uid = rs.getInt("uid") ;
				try {
					result.add(UserNameIDCache.getInstance().getName(uid)) ;
				} catch (Throwable e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
			rs.close();
			stmt.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return result;
	}
	
	/**
	 * check whether the user is member of the group
	 * @param groupID
	 * @param userID
	 * @return
	 */
	public static boolean isMember(int groupID,int userID){
        boolean result = false;
        HashSet<Integer> groups = new HashSet<Integer>(0);
		try {
			groups = GroupCache.getInstance().getGroupIDs(userID);
		} catch (Throwable e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        if(groups.contains(new Integer(groupID)))
        	result = true;
		return result;
	}
	
	/**
	 * create a new group, if exist return false
	 * @return false if exist
	 */
	public boolean serialize() {
		int groupID = getGroupIdByName(this.name);
		if ( groupID > 0 ) return false;
		Connection conn = DBConnectionFactory.getConnection();
		try {
			PreparedStatement pstmt = conn.prepareStatement("insert into edit_group(name, admin_id) values(?,?)");
			pstmt.setString(1, name);
			try {
				pstmt.setInt(2, UserNameIDCache.getInstance().getUserID(admin));
			} catch (Throwable e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			pstmt.executeUpdate();
			pstmt.close();
			conn.close();
			groupID = Group.getGroupIdByName(name);
			ArrayList<String> mem = new ArrayList<String>();
			mem.add(this.admin);
			addMember(groupID, mem);
			return true;
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return false;
	}
	
	@Override
	public int hashCode() {
		return name.hashCode();
	}
	
	@Override
	public boolean equals(Object obj) {
		if(obj instanceof Group){
		    return name.equals(((Group) obj).name);
		}
		return false;
	}
	public static void main(String[] args) {
		ArrayList<String> users = new ArrayList<String>();
		users.add("ssgong") ;
		users.add("gss") ;
		Group.addMember(2, users) ;
	}
}
